///////////////////////////////////////////////////////////////////////////////////// // Project : MATLAB PID CONTROL // // Version : 1.0 // // Date : 4/26/2008 // // Author : Kirk Fitzpatrick // // Company : Private user // // Comments: This program will act as a communication buffer to recieve position // // values from the slave via SPI and pass them to matlab via USART. // // Matlab will exectute the control law and pass the new PWM values back // // to this chip, which will then send those values to the slave via SPI // // Chip type : ATmega8 // // Program type : Application // // Clock frequency : 20.000000 MHz // // Memory model : Small // // External SRAM size : 0 // // Data Stack size : 256 // ///////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include ///////////////////////////////////////////////////////////////////////////////////// // GLOBAL VARIABLE DECLARATION // ///////////////////////////////////////////////////////////////////////////////////// char pen_pos_high, pen_pos_low; char mot_pos_high, mot_pos_low; char pwm_high, pwm_low; int pwm, pen_position, mot_position; ///////////////////////////////////////////////////////////////////////////////////// // INTERUPT DECLATATION // ///////////////////////////////////////////////////////////////////////////////////// interrupt [TIM1_COMPA] void timer1_compa_isr(void); ///////////////////////////////////////////////////////////////////////////////////// // FUNCTION DECLATATIONS // ///////////////////////////////////////////////////////////////////////////////////// void control_func(); void main(void) { ///////////////////////////////////////////////////////////////////////////////////// // PORTB contains the pinns for SPI comunication. The port is as follows: // // PORTB.1 OCRA OUTPUT // // PORTB.2 SS OUTPUT // // PORTB.3 MOSI OUTPUT // // PORTB.4 MISO INPUT // // PORTB.5 SCK OUTPUT // ///////////////////////////////////////////////////////////////////////////////////// PORTB=0x04; DDRB=0x2E; ///////////////////////////////////////////////////////////////////////////////////// // Timer/Counter 1 initialization // // Clock source: System Clock // // Clock value: 78.125 kHz // // Mode: Normal top=FFFFh // // OC1A output: Toggle // // Input Capture on Falling Edge // // Compare A Match Interrupt: On // ///////////////////////////////////////////////////////////////////////////////////// TCCR1A=0x40; TCCR1B=0x04; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; ///////////////////////////////////////////////////////////////////////////////////// // USART initialization // // Communication Parameters: 8 Data, 1 Stop, No Parity // // USART Receiver: On // // USART Transmitter: On // // USART Mode: Asynchronous // // USART Baud Rate: 115200 // ///////////////////////////////////////////////////////////////////////////////////// UCSRA=0x00; UCSRB=0x18; UCSRC=0x86; UBRRH=0x00; UBRRL=0x0A; ///////////////////////////////////////////////////////////////////////////////////// // Timer(s)/Counter(s) Interrupt(s) initialization // ///////////////////////////////////////////////////////////////////////////////////// TIMSK=0x10; ///////////////////////////////////////////////////////////////////////////////////// // SPI initialization // // SPI Type: Master // // SPI Clock Rate: 1250.000 kHz // // SPI Clock Phase: Cycle Half // // SPI Clock Polarity: Low // // SPI Data Order: MSB First // ///////////////////////////////////////////////////////////////////////////////////// SPCR=0x51; SPSR=0x00; ///////////////////////////////////////////////////////////////////////////////////// // Analog Comparator initialization // // Analog Comparator: Off // // Analog Comparator Input Capture by Timer/Counter 1: Off // ///////////////////////////////////////////////////////////////////////////////////// ACSR=0x80; SFIOR=0x00; ///////////////////////////////////////////////////////////////////////////////////// // GLOBAL INTERUPTS ENABLED // ///////////////////////////////////////////////////////////////////////////////////// #asm("sei") while (1){ putchar(pen_pos_high); putchar(pen_pos_low); putchar(mot_pos_high); putchar(mot_pos_low); pwm_high=getchar(); pwm_low=getchar(); pwm = ((signed int) pwm_high<<8)|pwm_low; pen_position=(((unsigned) pen_pos_high)<<8)|pen_pos_low; mot_position=(((unsigned) mot_pos_high)<<8)|mot_pos_low; } } ///////////////////////////////////////////////////////////////////////////////////// // CONTROL FUNCTION // ///////////////////////////////////////////////////////////////////////////////////// void control_func(){ PORTB&=0xFB; // Set SS* low to indicate communication spi(0); // Buffer spi(0); // Buffer pen_pos_high=spi(pwm_high); pen_pos_low=spi(pwm_low); mot_pos_high=spi(0); mot_pos_low=spi(0); PORTB|=0x04; } ///////////////////////////////////////////////////////////////////////////////////// // TIMER INTERUPTS FOR CONTROL TIMING // ///////////////////////////////////////////////////////////////////////////////////// interrupt [TIM1_COMPA] void timer1_compa_isr(void) { OCR1A+=39; //1kHz //78; // 500 Hz interupt control_func(); }